<template>
  <client-only>
    <div class="min-h-screen py-8 bg-white">
      <div class="max-w-4xl mx-auto px-4">
        <h1 class="text-3xl font-bold text-center mb-6">印章生成器</h1>

        <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
          <!-- Controls -->
          <div>
            <div class="space-y-4">
              <label class="block">
                <div class="text-sm text-gray-700 mb-1">主体文字</div>
                <input v-model="mainText" class="w-full border rounded px-3 py-2" placeholder="公司/机构名称" />
              </label>

              <label class="block">
                <div class="text-sm text-gray-700 mb-1">中心内容</div>
                <input v-model="centerText" class="w-full border rounded px-3 py-2" placeholder="★ 或 文本" />
              </label>

              <label class="block">
                <div class="text-sm text-gray-700 mb-1">底部文字</div>
                <input v-model="bottomText" class="w-full border rounded px-3 py-2" placeholder="印章专用章" />
              </label>

              <label class="block">
                <div class="text-sm text-gray-700 mb-1">印章颜色</div>
                <input type="color" v-model="color" class="w-16 h-10 p-0" />
              </label>

              <label class="block">
                <div class="text-sm text-gray-700 mb-1">主体文字大小 ({{ Math.round(size * mainFontScale) }}px)</div>
                <input type="range" min="0.04" max="0.12" step="0.005" v-model.number="mainFontScale" class="w-full" />
              </label>

              <label class="block">
                <div class="text-sm text-gray-700 mb-1">中心内容大小 ({{ Math.round(size * centerFontScale) }}px)</div>
                <input type="range" min="0.08" max="0.32" step="0.01" v-model.number="centerFontScale" class="w-full" />
              </label>

              <div class="flex items-center space-x-3">
                <label class="flex items-center space-x-2">
                  <input type="checkbox" v-model="showInnerBorder" />
                  <span class="text-sm">显示内边框</span>
                </label>
                <label class="flex items-center space-x-2">
                  <span class="text-sm">尺寸</span>
                  <select v-model="size" class="border rounded px-2 py-1">
                    <option value="160">160×160</option>
                    <option value="240">240×240</option>
                    <option value="320">320×320</option>
                    <option value="480">480×480</option>
                  </select>
                </label>
              </div>

              <div class="flex space-x-3">
                <button @click="generate" class="bg-blue-600 text-white px-4 py-2 rounded">生成印章</button>
                <button @click="download" class="bg-green-600 text-white px-4 py-2 rounded">下载保存</button>
              </div>

              <div v-if="errorMessage" class="text-sm text-red-600 mt-2">{{ errorMessage }}</div>

              <div class="mt-4 text-sm text-gray-500 p-4 bg-blue-50 rounded">
                工具简介：本站在线生成的印章图片仅供娱乐，请勿用于非法用途。
              </div>
            </div>
          </div>

          <!-- Preview -->
          <div class="flex flex-col items-center">
            <div class="mb-4">
              <canvas ref="canvas" :width="size" :height="size" class="bg-white"></canvas>
            </div>
            <div class="text-sm text-gray-600">预览（可下载PNG）</div>
          </div>
        </div>
      </div>
    </div>
  </client-only>
</template>

<script setup>
import { ref, onMounted, watch } from 'vue'

const mainText = ref('月亮市天天搞笑娱乐工作室')
const centerText = ref('★')
const bottomText = ref('搞笑专用章')
const color = ref('#ff0000')
const showInnerBorder = ref(true)
const size = ref(320)

const canvas = ref(null)
const mainFontScale = ref(0.07)
const centerFontScale = ref(0.18)
const bottomFontScale = ref(0.07)
const errorMessage = ref('')

function drawArcText(ctx, text, cx, cy, radius, centerAngle) {
  // Draw text along an arc centered at centerAngle (radians) around cx,cy.
  // Place characters left->right across the arc, measuring each char width
  // and converting to angle = width / radius. For top arcs (centerAngle < 0)
  // we rotate by midAngle + PI/2 so characters are upright; for bottom arcs
  // (centerAngle > 0) we rotate by midAngle - PI/2 to keep characters upright.
  if (!text) return
  const chars = text.split('')
  const widths = chars.map(ch => ctx.measureText(ch).width)
  const totalLen = widths.reduce((s, v) => s + v, 0)
  const totalAngle = totalLen / radius

  let startAngle = centerAngle - totalAngle / 2

  ctx.save()
  ctx.translate(cx, cy)
  let acc = 0
  for (let i = 0; i < chars.length; i++) {
    const ch = chars[i]
    const w = widths[i]
    const charAngle = w / radius
    const mid = startAngle + acc + charAngle / 2

    ctx.save()
    // rotate to the character mid-angle
    // choose rotation offset so characters remain upright
    const rotOffset = centerAngle > 0 ? -Math.PI / 2 : Math.PI / 2
    ctx.rotate(mid + rotOffset)
    ctx.textAlign = 'center'
    ctx.textBaseline = 'middle'
    ctx.fillText(ch, 0, -radius)
    ctx.restore()

    acc += charAngle
  }
  ctx.restore()
}

function generateStamp() {
  const c = canvas.value
  if (!c) return
  const ctx = c.getContext('2d')
  const w = Number(size.value)
  const h = w
  c.width = w
  c.height = h
  ctx.clearRect(0, 0, w, h)

  const cx = w / 2
  const cy = h / 2
  const outerRadius = Math.min(w, h) * 0.45
  const innerRadius = outerRadius - (showInnerBorder.value ? (outerRadius * 0.06) : 0)

  // background transparent
  ctx.clearRect(0, 0, w, h)

  // outer circle
  ctx.strokeStyle = color.value
  ctx.lineWidth = Math.max(2, Math.round(w * 0.012))
  ctx.beginPath()
  ctx.arc(cx, cy, outerRadius, 0, Math.PI * 2)
  ctx.stroke()

  // inner circle
  if (showInnerBorder.value) {
    ctx.lineWidth = Math.max(1, Math.round(w * 0.006))
    ctx.beginPath()
    ctx.arc(cx, cy, innerRadius, 0, Math.PI * 2)
    ctx.stroke()
  }

  // center star or text
  ctx.fillStyle = color.value
  ctx.textAlign = 'center'
  ctx.textBaseline = 'middle'
  // center large character
  ctx.font = `${Math.round(w * centerFontScale.value)}px serif`
  ctx.fillText(centerText.value, cx, cy - (w * 0.03))

  // bottom text
  ctx.fillStyle = color.value
  ctx.font = `${Math.round(w * bottomFontScale.value)}px sans-serif`
  ctx.textAlign = 'center'
  ctx.fillText(bottomText.value, cx, cy + outerRadius * 0.6)

  // arc top text (main text)
  ctx.fillStyle = color.value
  ctx.font = `${Math.round(w * mainFontScale.value)}px sans-serif`
  const usableRadius = outerRadius - (w * 0.08)
  // measure total angle needed for full text
  const tmp = ctx
  const chars = mainText.value.split('')
  const widths = chars.map(ch => tmp.measureText(ch).width)
  const totalLen = widths.reduce((s, v) => s + v, 0)
  const neededAngle = totalLen / usableRadius
  const maxTopAngle = Math.PI * 0.95 // slightly less than half circle to avoid edges
  const maxAllowed = Math.PI * 1.9 // allow extension into lower half but avoid full wrap

  // clear previous error
  errorMessage.value = ''

  if (neededAngle <= maxTopAngle) {
    // fits on top half
    drawArcText(ctx, mainText.value, cx, cy, usableRadius, -Math.PI / 2)
  } else if (neededAngle <= maxAllowed) {
    // allow the main text to extend into the lower half (centered at top)
    drawArcText(ctx, mainText.value, cx, cy, usableRadius, -Math.PI / 2)
  } else {
    // too long to draw without overlap — show error and don't draw main text
    errorMessage.value = '主体文字过长，生成失败，请减少文字后重试'
  }
}

function generate() {
  generateStamp()
}

function download() {
  const c = canvas.value
  if (!c) return
  if (errorMessage.value) {
    // prevent download when generation failed
    alert(errorMessage.value)
    return
  }
  const url = c.toDataURL('image/png')
  const link = document.createElement('a')
  link.href = url
  link.download = `${(mainText.value || 'stamp').replace(/\s+/g, '_')}.png`
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

onMounted(() => {
  generateStamp()
})

watch([mainText, centerText, bottomText, color, showInnerBorder, size, mainFontScale, centerFontScale, bottomFontScale], () => {
  // small debounce via nextTick isn't necessary for simple inputs
  generateStamp()
})
</script>

<style scoped>
.tool-actions { }
</style>
